﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Sharpie.Libs
{
	public class Screen : DrawableGameComponent
	{
		SpriteBatch spriteBatch;

		public bool IsHidden
		{
			get
			{
				return _hidden;
			}
		}
		public HideStyle HideAnimation
		{
			get
			{
				return _hideStyle;
			}
			set
			{
				_hideStyle = value;
				SkipAnimation();
			}
		}
		bool _hidding, _hidden;
		HideStyle _hideStyle;
		DrawableGameComponent dgc;
		Viewport currentViewport, defaultViewport;
		Texture2D blackT;
		Point hidePos, position;
		int posSpeed;
		float opacity;
		float opacitySpeed = 0.06F;

		public Screen(DrawableGameComponent drawableGameComponent)
			: base(drawableGameComponent.Game)
		{
			dgc = drawableGameComponent;
			HideAnimation = HideStyle.Fade;
			Initialize();
		}

		public override void Initialize()
		{
			base.Initialize();
			posSpeed = GraphicsDevice.Viewport.Width / 15;
			spriteBatch = new SpriteBatch(GraphicsDevice);
			defaultViewport = GraphicsDevice.Viewport;
			Hide();
			SkipAnimation();
			dgc.Initialize();
			dgc.Update(new GameTime());
		}

		public enum HideStyle
		{
			Fade,
			SlideLeft,
			SlideRight,
		}

		protected override void LoadContent()
		{
			base.LoadContent();
			blackT = new Texture2D(GraphicsDevice, 1, 1);
			blackT.SetData(new Color[] { Color.Black });
		}

		public override void Update(GameTime gameTime)
		{
			base.Update(gameTime);

			if (_hidding)
			{
				switch (_hideStyle)
				{
					case HideStyle.Fade:
						if (opacity != 1F)
						{
							opacity += opacitySpeed;
							if (opacity >= 1F)
							{
								opacity = 2F;
								_hidden = true;
							}
						}
						break;
					case HideStyle.SlideLeft:
						if (position.X > hidePos.X)
						{
							position.X -= posSpeed;
							if (position.X <= hidePos.X)
							{
								position.X = hidePos.X;
								_hidden = true;
							}
						}
						break;
					case HideStyle.SlideRight:
						if (position.X < hidePos.X)
						{
							position.X += posSpeed;
							if (position.X >= hidePos.X)
							{
								position.X = hidePos.X;
								_hidden = true;
							}
						}
						break;
				}
			}
			else
			{
				switch (_hideStyle)
				{
					case HideStyle.Fade:
						if (opacity != 0F)
						{
							if (_hidden)
								_hidden = false;
							opacity -= opacitySpeed;
							if (opacity < 0F)
								opacity = 0F;
						}
						break;
					case HideStyle.SlideLeft:
						if (position.X < 0)
						{
							if (_hidden)
								_hidden = false;
							position.X += posSpeed;
							if (position.X > 0)
								position.X = 0;
						}
						break;
					case HideStyle.SlideRight:
						if (position.X > 0)
						{
							if (_hidden)
								_hidden = false;
							position.X -= posSpeed;
							if (position.X < 0)
								position.X = 0;
						}
						break;
				}
			}
			if (position == Point.Zero & opacity == 0F)
				dgc.Update(gameTime);
			currentViewport = new Viewport(position.X, position.Y, defaultViewport.Width, defaultViewport.Height);
		}

		public override void Draw(GameTime gameTime)
		{
			base.Draw(gameTime);
			if (!IsHidden)
			{
				GraphicsDevice.Viewport = currentViewport;
				dgc.Draw(gameTime);
				GraphicsDevice.Viewport = defaultViewport;
				if (_hideStyle == HideStyle.Fade)
				{
					spriteBatch.Begin();
					spriteBatch.Draw(blackT, GraphicsDevice.Viewport.Bounds, Color.Black * opacity);
					spriteBatch.End();
				}
			}
		}

		public void Hide()
		{
			_hidding = true;
		}

		public void SkipAnimation()
		{
			switch (_hideStyle)
			{
				case HideStyle.SlideLeft:
					hidePos = new Point(-GraphicsDevice.Viewport.Width, 0);
					opacity = 0F;
					if (_hidding)
					{
						position = hidePos;
						_hidden = true;
					}
					else
					{
						position = new Point(0, 0);
						_hidden = false;
					}
					break;
				case HideStyle.SlideRight:
					hidePos = new Point(GraphicsDevice.Viewport.Width, 0);
					opacity = 0F;
					if (_hidding)
					{
						position = hidePos;
						_hidden = true;
					}
					else
					{
						position = new Point(0, 0);
						_hidden = false;
					}
					break;
				case HideStyle.Fade:
					hidePos = new Point(0, 0);
					position = new Point(0, 0);
					if (_hidding)
					{
						opacity = 2F;
						_hidden = true;
					}
					else
					{
						opacity = 0F;
						_hidden = false;
					}
					break;
			}
		}

		public void Show()
		{
			_hidding = false;
		}
	}
}
